home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / tcpdump-3.0 / print-wb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-15  |  9.8 KB  |  446 lines

  1. /*
  2.  * Copyright (c) 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-wb.c,v 1.14 94/06/14 20:18:50 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29.  
  30. #include <netinet/in.h>
  31.  
  32. #include <stdio.h>
  33.  
  34. #include "interface.h"
  35. #include "addrtoname.h"
  36.  
  37. /* XXX need to add byte-swapping macros! */
  38.  
  39. /*
  40.  * Largest packet size.  Everything should fit within this space.
  41.  * For instance, multiline objects are sent piecewise.
  42.  */
  43. #define MAXFRAMESIZE 1024
  44.  
  45. /*
  46.  * Multiple drawing ops can be sent in one packet.  Each one starts on a
  47.  * an even multiple of DOP_ALIGN bytes, which must be a power of two.
  48.  */
  49. #define DOP_ALIGN 4
  50. #define DOP_ROUNDUP(x)    ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
  51. #define DOP_NEXT(d)\
  52.     ((struct dophdr*)((u_char *)(d) + \
  53.               DOP_ROUNDUP(ntohs((d)->dh_len) + sizeof(*(d)))))
  54.  
  55. /*
  56.  * Format of the whiteboard packet header.
  57.  * The transport level header.
  58.  */
  59. struct pkt_hdr {
  60.     u_int32 ph_src;        /* site id of source */
  61.     u_int32 ph_ts;        /* time stamp (for skew computation) */
  62.     u_short ph_version;    /* version number */
  63.     u_char ph_type;        /* message type */
  64.     u_char ph_flags;    /* message flags */
  65. };
  66.  
  67. /* Packet types */
  68. #define PT_DRAWOP    0    /* drawing operation */
  69. #define PT_ID        1    /* announcement packet */
  70. #define PT_RREQ        2    /* repair request */
  71. #define PT_RREP        3    /* repair reply */
  72. #define PT_KILL        4    /* terminate participation */
  73. #define PT_PREQ         5       /* page vector request */
  74. #define PT_PREP         7       /* page vector reply */
  75.  
  76. /* flags */
  77. #define PF_USER        0x01    /* hint that packet has interactive data */
  78. #define PF_VIS        0x02    /* only visible ops wanted */
  79.  
  80. struct PageID {
  81.     u_int32 p_sid;        /* session id of initiator */
  82.     u_int32 p_uid;        /* page number */
  83. };
  84.  
  85. struct dophdr {
  86.     u_int32  dh_ts;        /* sender's timestamp */
  87.     u_short    dh_len;        /* body length */
  88.     u_char    dh_flags;
  89.     u_char    dh_type;    /* body type */
  90.     /* body follows */
  91. };
  92. /*
  93.  * Drawing op sub-types.
  94.  */
  95. #define DT_RECT         2
  96. #define DT_LINE         3
  97. #define DT_ML           4
  98. #define DT_DEL          5
  99. #define DT_XFORM        6
  100. #define DT_ELL          7
  101. #define DT_CHAR         8
  102. #define DT_STR          9
  103. #define DT_NOP          10
  104. #define DT_PSCODE       11
  105. #define DT_PSCOMP       12
  106. #define DT_REF          13
  107. #define DT_SKIP         14
  108. #define DT_HOLE         15
  109. #define DT_MAXTYPE      15
  110.  
  111. /*
  112.  * A drawing operation.
  113.  */
  114. struct pkt_dop {
  115.     struct PageID pd_page;    /* page that operations apply to */
  116.     u_int32    pd_sseq;    /* start sequence number */
  117.     u_int32    pd_eseq;    /* end sequence number */
  118.     /* drawing ops follow */
  119. };
  120.  
  121. /*
  122.  * A repair request.
  123.  */
  124. struct pkt_rreq {
  125.         u_int32 pr_id;           /* source id of drawops to be repaired */
  126.         struct PageID pr_page;           /* page of drawops */
  127.         u_int32 pr_sseq;         /* start seqno */
  128.         u_int32 pr_eseq;         /* end seqno*/
  129. };
  130.  
  131. /*
  132.  * A repair reply.
  133.  */
  134. struct pkt_rrep {
  135.     u_int32 pr_id;    /* original site id of ops  */
  136.     struct pkt_dop pr_dop;
  137.     /* drawing ops follow */
  138. };
  139.  
  140. struct id_off {
  141.         u_int32 id;
  142.         u_int32 off;
  143. };
  144.  
  145. struct pgstate {
  146.     u_int32 slot;
  147.     struct PageID page;
  148.     u_short nid;
  149.     u_short rsvd;
  150.         /* seqptr's */
  151. };
  152.  
  153. /*
  154.  * An announcement packet.
  155.  */
  156. struct pkt_id {
  157.     u_int32 pi_mslot;
  158.         struct PageID    pi_mpage;        /* current page */
  159.     struct pgstate pi_ps;
  160.         /* seqptr's */
  161.         /* null-terminated site name */
  162. };
  163.  
  164. struct pkt_preq {
  165.         struct PageID  pp_page;
  166.         u_int32  pp_low;
  167.         u_int32  pp_high;
  168. };
  169.  
  170. struct pkt_prep {
  171.         u_int32  pp_n;           /* size of pageid array */
  172.         /* pgstate's follow */
  173. };
  174.  
  175. static int
  176. wb_id(const struct pkt_id *id, int len)
  177. {
  178.     int i;
  179.     const char *cp;
  180.     const struct id_off *io;
  181.     char c;
  182.     int nid;
  183.  
  184.     len -= sizeof(*id);
  185.     if (len < 0) {
  186.         printf(" truncated-wb-id!");
  187.         return (0);
  188.     }
  189.     if ((u_char *)(id + 1) > snapend)
  190.         return (-1);
  191.     nid = ntohs(id->pi_ps.nid);
  192.     len -= sizeof(*io) * nid;
  193.     if (len < 0) {
  194.         printf(" truncated-wb-id!");
  195.         return (0);
  196.     }
  197.     io = (struct id_off *)(id + 1);
  198.     cp = (char *)(io + nid);
  199.     if ((u_char *)cp + len > snapend)
  200.         return (-1);
  201.  
  202.     printf(" wb-id: %d/%s:%d (max %d/%s:%d) ",
  203.            ntohl(id->pi_ps.slot),
  204.            ipaddr_string(&id->pi_ps.page.p_sid),
  205.            ntohl(id->pi_ps.page.p_uid),
  206.            ntohl(id->pi_mslot),
  207.            ipaddr_string(&id->pi_mpage.p_sid),
  208.            ntohl(id->pi_mpage.p_uid));
  209.  
  210.     if (cp[len - 1] != '\0')
  211.         printf("(unterm!) ");
  212.  
  213.     fn_print((u_char *)cp, (u_char *)cp + len);
  214.  
  215.     c = '<';
  216.     for (i = 0; i < nid; ++io, ++i) {
  217.         printf("%c%s:%d", c, ipaddr_string(&io->id), ntohl(io->off));
  218.         c = ',';
  219.     }
  220.     printf(">");
  221.     return (0);
  222. }
  223.  
  224. static int
  225. wb_rreq(const struct pkt_rreq *rreq, int len)
  226. {
  227.     if (len < sizeof(*rreq)) {
  228.         printf(" truncated-wb-rreq!");
  229.         return (0);
  230.     }
  231.     if ((u_char *)(rreq + 1) > snapend)
  232.         return (-1);
  233.  
  234.     printf(" wb-rreq: please repair %s %s:%ld<%ld:%ld>",
  235.            ipaddr_string(&rreq->pr_id),
  236.            ipaddr_string(&rreq->pr_page.p_sid), ntohl(rreq->pr_page.p_uid),
  237.            ntohl(rreq->pr_sseq), ntohl(rreq->pr_eseq));
  238.     return (0);
  239. }
  240.  
  241. static int
  242. wb_preq(const struct pkt_preq *preq, int len)
  243. {
  244.     if (len < sizeof(*preq)) {
  245.         printf(" truncated-wb-preq!");
  246.         return (0);
  247.     }
  248.     if ((u_char *)(preq + 1) > snapend)
  249.         return (-1);
  250.  
  251.     printf(" wb-preq: need %d/%s:%ld",
  252.            ntohl(preq->pp_low),
  253.            ipaddr_string(&preq->pp_page.p_sid),
  254.            ntohl(preq->pp_page.p_uid));
  255.     return (0);
  256. }
  257.  
  258. static int
  259. wb_prep(const struct pkt_prep *prep, int len)
  260. {
  261.     int n;
  262.     const struct pgstate* ps;
  263.     const u_char* ep = snapend;
  264.  
  265.     if (len < sizeof(*prep)) {
  266.         printf(" truncated-wb-prep!");
  267.         return (0);
  268.     }
  269.     printf(" wb-prep:");
  270.     n = ntohl(prep->pp_n);
  271.     ps = (const struct pgstate*)(prep + 1);
  272.     while (--n >= 0 && (u_char*)ps < ep) {
  273.         const struct id_off *io, *ie;
  274.         char c = '<';
  275.  
  276.         printf(" %lu/%s:%lu", ntohl(ps->slot),
  277.             ipaddr_string(&ps->page.p_sid),
  278.             ntohl(ps->page.p_uid));
  279.         io = (struct id_off*)(ps + 1);
  280.         for (ie = io + ps->nid; io < ie && (u_char*)io < ep; ++io) {
  281.             printf("%c%s:%lu", c, ipaddr_string(&io->id),
  282.                 ntohl(io->off));
  283.             c = ',';
  284.         }
  285.         printf(">");
  286.         ps = (struct pgstate*)io;
  287.     }
  288.     return ((u_char*)ps <= ep? 0 : -1);
  289. }
  290.  
  291.  
  292. char *dopstr[] = {
  293.     "dop-0!",
  294.     "dop-1!",
  295.     "RECT",
  296.     "LINE",
  297.     "ML",
  298.     "DEL",
  299.     "XFORM",
  300.     "ELL",
  301.     "CHAR",
  302.     "STR",
  303.     "NOP",
  304.     "PSCODE",
  305.     "PSCOMP",
  306.     "REF",
  307.     "SKIP",
  308.     "HOLE",
  309. };
  310.  
  311. static int
  312. wb_dops(const struct dophdr *dh, u_int32 ss, u_int32 es)
  313. {
  314.     printf(" <");
  315.     for ( ; ss <= es; ++ss) {
  316.         register int t = dh->dh_type;
  317.  
  318.         if (t > DT_MAXTYPE)
  319.             printf(" dop-%d!", t);
  320.         else {
  321.             printf(" %s", dopstr[t]);
  322.             if (t == DT_SKIP || t == DT_HOLE) {
  323.                 int ts = ntohl(dh->dh_ts);
  324.                 printf("%d", ts - ss + 1);
  325.                 if (ss > ts || ts > es) {
  326.                     printf("[|]");
  327.                     if (ts < ss)
  328.                         return (0);
  329.                 }
  330.                 ss = ts;
  331.             }
  332.         }
  333.         dh = DOP_NEXT(dh);
  334.         if ((u_char*)dh >= snapend) {
  335.             printf("[|wb]");
  336.             break;
  337.         }
  338.     }
  339.     printf(" >");
  340.     return (0);
  341. }
  342.  
  343. static int
  344. wb_rrep(const struct pkt_rrep *rrep, int len)
  345. {
  346.     const struct pkt_dop *dop = &rrep->pr_dop;
  347.  
  348.     len -= sizeof(*rrep);
  349.     if (len < 0) {
  350.         printf(" truncated-wb-rrep!");
  351.         return (0);
  352.     }
  353.     if ((u_char *)(rrep + 1) > snapend)
  354.         return (-1);
  355.  
  356.     printf(" wb-rrep: for %s %s:%d<%ld:%ld>",
  357.            ipaddr_string(&rrep->pr_id),
  358.            ipaddr_string(&dop->pd_page.p_sid), ntohl(dop->pd_page.p_uid),
  359.            ntohl(dop->pd_sseq), ntohl(dop->pd_eseq));
  360.  
  361.     return (wb_dops((const struct dophdr*)(dop + 1),
  362.             ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
  363. }
  364.  
  365. static int
  366. wb_drawop(const struct pkt_dop *dop, int len)
  367. {
  368.     len -= sizeof(*dop);
  369.     if (len < 0) {
  370.         printf(" truncated-wb-dop!");
  371.         return (0);
  372.     }
  373.     if ((u_char *)(dop + 1) > snapend)
  374.         return (-1);
  375.  
  376.     printf(" wb-dop: %s:%d<%ld:%ld>",
  377.            ipaddr_string(&dop->pd_page.p_sid), ntohl(dop->pd_page.p_uid),
  378.            ntohl(dop->pd_sseq), ntohl(dop->pd_eseq));
  379.  
  380.     return (wb_dops((const struct dophdr*)(dop + 1),
  381.             ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
  382. }
  383.  
  384. /*
  385.  * Print whiteboard multicast packets.
  386.  */
  387. void
  388. wb_print(register const void *hdr, register int len)
  389. {
  390.     register const struct pkt_hdr* ph;
  391.  
  392.     ph = (const struct pkt_hdr*)hdr;
  393.     len -= sizeof(*ph);
  394.     if (len < 0) {
  395.         printf(" truncated-wb!");
  396.         return;
  397.     }
  398.     if ((u_char *)(ph + 1) > snapend) {
  399.  trunc:
  400.         printf("[|wb]");
  401.         return;
  402.     }
  403.     if (ph->ph_flags)
  404.         printf("*");
  405.     switch (ph->ph_type) {
  406.  
  407.     case PT_KILL:
  408.         printf(" wb-kill");
  409.         break;
  410.  
  411.     case PT_ID:
  412.         if (wb_id((struct pkt_id *)(ph + 1), len) < 0)
  413.             goto trunc;
  414.         break;
  415.  
  416.     case PT_RREQ:
  417.         if (wb_rreq((struct pkt_rreq *)(ph + 1), len) < 0)
  418.             goto trunc;
  419.         break;
  420.  
  421.     case PT_RREP:
  422.         if (wb_rrep((struct pkt_rrep *)(ph + 1), len) < 0)
  423.             goto trunc;
  424.         break;
  425.  
  426.     case PT_DRAWOP:
  427.         if (wb_drawop((struct pkt_dop *)(ph + 1), len) < 0)
  428.             goto trunc;
  429.         break;
  430.  
  431.     case PT_PREQ:
  432.         if (wb_preq((struct pkt_preq *)(ph + 1), len) < 0)
  433.             goto trunc;
  434.         break;
  435.  
  436.     case PT_PREP:
  437.         if (wb_prep((struct pkt_prep *)(ph + 1), len) < 0)
  438.             goto trunc;
  439.         break;
  440.  
  441.     default:
  442.         printf(" wb-%d!", ph->ph_type);
  443.         return;
  444.     }
  445. }
  446.